#pragma once

#include "Character/buff/BuffEffectInfo.h"


#include "Part.h"
#include "ProtoBuffer/AllProtocol.h"
#include <iostream>

#define BUFF_PART_TIME_DEAD_BUFF 0

struct BuffEventParam
{
	BuffEventParam()
	{
		m_targetCid = 0;
		m_damagedValue = 0;
		m_skillId = 0;
	}

	void Clear()
	{
		m_targetCid = 0;
		m_damagedValue = 0;
		m_skillId = 0;
	}
	CharIDType m_targetCid;
	uint32_t   m_skillId;
	uint32_t	  m_damagedValue;
};

class BuffPart : public Part
{
public:
	using BuffBagEffectMap = std::unordered_map<uint32_t, BuffBagEffectInfo*>;
	using BuffBagEffectList = std::list <uint32_t> ;
public:
	BuffPart();
	virtual ~BuffPart();
	bool Init(Creature *pMaster, uint32_t partType, CharacterDBInfo* pCharacterDB = nullptr);
	bool UnInit();
	void OnExecute(uint16_t nEventID, uint64_t nSrcID, uint8_t bySrcType, void *pContext, int32_t nLen);
	bool OnMsgHandle(uint32_t cmd, const char* data, uint32_t len);
	void OnTimer(uint32_t nTimerId);

	void AllBuffBagFadeOut();
	void ClearBuffBag();
public:
	virtual void BeforeChangeLogic(); //生物切换逻辑节点
	virtual bool SynOnLogin(PlayerClientInfo& playerInfo);
	virtual bool SaveDB(CharacterDBInfo& characterDB);
	virtual bool GetAllBuffInfo(::ProtoBuf::msgBuffList* pBuffData);
	//生物登出入口
	virtual void SynLogout();
public:
	BuffBagEffectMap& GetBuffBagList() { return m_buffBagList; }
	BuffBagEffectInfo* CreateBuffBag() { return new BuffBagEffectInfo(); }
	void			   DeleteBuffBag(BuffBagEffectInfo * buffBag) { if (buffBag) delete buffBag; }
public:
	BuffBagEffectInfo* BuffEffect_RegisterEffect(Creature* pSender, uint32_t skillId, uint32_t skillLevel, uint32_t stateBagId, uint32_t stateBagRate, 
		int32_t stateBagTime, const std::vector<int32_t>& params, bool syn = false, uint32_t targetType = BUFF_BAG_TARGET_TYPE_ENEMY);//先考虑叠加，驱散，免疫

	BuffBagEffectInfo* GetBuffBag(uint32_t buffBagInstId);
protected:
	bool BuffEffect_CanRegisterEffect(BuffBagEffectInfo* pBuffBag, const std::vector<int32_t>& params); //主要做状态包的叠加和驱散
	bool BuffEffect_RegisterEffectImp(BuffBagEffectInfo* pBuffBag, bool syn);//状态包叠加计算后
	bool BuffEffect_PushToDelayedTimeListImp(BuffBagEffectInfo* pBuffBag);//状态包叠加计算后
protected:
	uint32_t BuffBagList_CountBag(uint32_t stateBagId); //计算stateBagId在list里的个数
	void BuffBagList_EraseBag(uint32_t stateBagId); //删除所有stateBagId
	bool BuffBagList_FirstBiggerOverrides(uint32_t stateBagId, const std::vector<int32_t>& params); //第一个参数效果大的覆盖效果小的, return true
	void BuffBagList_EraseBagRestTimeLitter(uint32_t stateBagId, uint64_t stateBagTime); //删除剩余时间短的
public:
	void BuffEffect_Update(uint64_t tick);
	void BuffEffect_CleanupAllFadeOutEffects();
	void BuffEffect_CleanupAllFadeOutEffects(uint32_t skillId);
	void BuffEffect_CleanupAllFadeOutEffects(BuffInfoEndType endType); //结束满足结束类型的buff bag
	void BuffEffect_CleanupAllFadeOutEffects(BuffBagEffectInfo* buffBag, bool isSendEndEffect = true);
	bool BuffEffect_IsContainEndType(BuffBagEffectInfo* buffBag, int32_t endType);
	bool BuffEffect_IsContainStartType(BuffBagEffectInfo* buffBag, int32_t endType);
public:
	void BuffEffect_SendAllEffectMsg();
	void BuffEffect_SendStartEffectMsg(const BuffBagEffectInfo* buffBag);
	void BuffEffect_SendEndEffectMsg(const BuffBagEffectInfo* buffBag);
	void BuffEffect_SendMissMsg(const BuffBagEffectInfo* buffBag); //buff bag 被丢弃，可能是没叠加上或被免疫
public:
	//存在修改玩家伤害的特效是调用，比如生命盾
	virtual void BuffEffect_ReduceDamage(Creature* pAttack, uint32_t skillId, int32_t &damage);
	//virtual void BuffEffect_ReduceDamage(BuffBagEffectInfo* buffBag, int32_t &damage); //

	////对敌方增加额外伤害
	virtual void BuffEffect_AddExtraDamage(Creature* pBeAttacked, uint32_t skillId, int32_t &damage);
	//virtual void BuffEffect_AddExtraDamage(BuffBagEffectInfo* buffBag, int32_t &damage); //

	virtual bool BuffEffect_HasBuffBag(uint32_t stateBagId) { return BuffBagList_CountBag(stateBagId) > 0; }
public:
	void BuffEffect_EffectClassifed(BuffBagEffectInfo* buffBag); //对BuffBag分类
	void BuffEffect_ClearEffectClassifed(BuffBagEffectInfo* buffBag);
	static bool IsReduceDamageBuffBag(BuffBagEffectInfo* buffBag); //生命盾
	static bool IsAddExtraDamageBuffBag(BuffBagEffectInfo* buffBag);
	static bool IsRefixSkillBuffBag(BuffBagEffectInfo* buffBag); //refix skill
public:
	uint32_t	GetBuffDropGoldPercent() const { return m_buffDropGoldPercent; }
	void		AddBuffDropGoldPercent(uint64_t count) { m_buffDropGoldPercent += count; }
	void		DelBuffDropGoldPercent(uint64_t count);
public:
	BuffEventParam& GetBuffEventParam() { return m_buffEventParam; }
	void ClearBuffEventParam() { m_buffEventParam.Clear(); }
protected:
	BuffBagEffectMap		m_buffBagList;
protected:
	BuffBagEffectList		m_ReduceDamageBuffBag; //生命盾
	BuffBagEffectList		m_AddExtraDamageBuffBag;
	uint64_t					m_lastTime;
protected:
	uint64_t					m_buffDropGoldPercent;
protected:
	BuffEventParam			m_buffEventParam;
protected:
	bool						m_IsExistDeleteTimer;
protected:
	//对目前BUFF机制的一种补充
	::ProtoBuf::CharacterBuffData dbData;
};
